#!/usr/bin/env python

import os
import sys
import re
import math
from math import exp,log
from barchart import *
import numpy as np
from os.path import join as joinpath

def usage():
    print '''\
Usage: %s -c <configuration-file>
''' % sys.argv[0]
    sys.exit(1)

def getopts(list, flags):
    import getopt
    try:
        opts, args = getopt.getopt(list, flags)
    except getopt.GetoptError:
        usage()

    return opts, args

work_dir = 'spec_workdir'
isa = 'trips'
inputset = 'ref'
home = os.environ['HOME']

result_dir = os.path.join(home, work_dir, 'backup', 'backup')

output_dir = os.path.join(home, work_dir, 'figs')

int_benchmarks = ['gzip','vpr','gcc','mcf',
                  'perlbmk',
                  'crafty',
                  'parser',
                  'gap',
                  'vortex',
                  'bzip2',
                  'twolf',
                 ]

float_benchmarks = ['wupwise','swim',
                    'mgrid','applu','mesa','art',
                    'equake','ammp','apsi'] 

#int_benchmarks = ['wupwise','swim',
#                  'mgrid','applu',
#                  'mesa',
#                  'art',
#                  'equake','ammp','apsi'] 

all_benchmarks = int_benchmarks + float_benchmarks

class TempStat(object):
    stat = float(0.0)
    def __init__(self,bname,sname,config,**kwargs):
        self.bname = bname
        self.sname = sname
        stats_file = os.path.join(result_dir, 'ogehl_chooser.csv')

        tmp_f = open(stats_file, 'r')
        if len(tmp_f.readlines()) == 0:
            sys.exit("Empty stats file:%s" % stats_file)

        tmp_f.close()

        tmp_pattern = config + sname
        for line in open(stats_file):
            l = line.split(',')
            if not l:
                continue
            if l[0] == tmp_pattern:
                self.stat = float(l[int_benchmarks.index(bname) + 1])
                break

    def data(self):
        return self.stat


class Stat(object):
    stat = float(0.0)
    def __init__(self,bname,sname,config,mode='normal',**kwargs):
        self.bname = bname
        self.sname = sname
        stats_file = os.path.join(result_dir, config,
                                  'stats', bname + '.txt')

        tmp_f = open(stats_file, 'r')
        if len(tmp_f.readlines()) == 0:
            sys.exit("Empty stats file:%s" % stats_file)

        tmp_f.close()

        if mode == 'normal':
            for line in open(stats_file):
                l = line.split()
                if not l:
                    continue
                l[0] = l[0].replace('system0','system')
                if l[0] == sname:
                    self.stat = float(l[1])
                    break
        elif mode == 'pdf':
            for line in open(stats_file):
                l = line.split()
                if not l:
                    continue
                l[0] = l[0].replace('system0','system')
                if l[0] == sname:
                    self.stat = (float(l[2].rstrip('%')) / 100.0)
                    break
        elif mode == 'cdf':
            for line in open(stats_file):
                l = line.split()
                if not l:
                    continue
                l[0] = l[0].replace('system0','system')
                if l[0] == sname:
                    self.stat = (float(l[3].rstrip('%')) / 100.0)
                    break
        else:
            sys.exit("Unknown mode while reading stats")

    
    def data(self):
        return self.stat

class TopN(object):

    statBaseNameSeq = 'system.cpu.commit.branchTypeTop100SeqPercent' 
    statBaseNameBr = 'system.cpu.commit.branchTypeTop100BranchPercent' 
    statBaseNameCall = 'system.cpu.commit.branchTypeTop100CallPercent' 
    statBaseNameRet = 'system.cpu.commit.branchTypeTop100RetPercent' 

    def __init__(self, bname, config, num, **kwargs):
        # Number of hyperblocks 100% dominated by Sequential target
        self.numSeqFullDom = 0
        # Number of hyperblocks 100% dominated by Branch target
        self.numBrFullDom = 0
        # Number of hyperblocks 100% dominated by Call target
        self.numCallFullDom = 0
        # Number of hyperblocks 100% dominated by Ret target
        self.numRetFullDom = 0

        # Number of hyperblocks dominated by Sequential target,
        # percentage of which is more than 50% and less than 100%.
        # All of the Rests are Branch targets. 
        self.numSeqHalfDom = 0
        # Number of hyperblocks dominated by Branch target,
        # percentage of which is more than 50% and less than 100%.
        # All of the Rests are Sequential targets. 
        self.numBrHalfDom = 0

        self.numSeqBr = 0

        # Number of hyperblocks which can not be attributed to the
        # above classes.
        self.numRests = 0

        total_num_instances = Stat(bname, \
                'system.cpu.commit.branchTypeMaxDist::samples', config, 'normal')

        if total_num_instances.data() < num:
            self.totalNumInstances = total_num_instances.data()
        else:
            self.totalNumInstances = num

        for i in range(int(self.totalNumInstances)):

            sname_seq = self.statBaseNameSeq + '::' + str(i)
            sname_br = self.statBaseNameBr + '::' + str(i)
            sname_call = self.statBaseNameCall + '::' + str(i)
            sname_ret = self.statBaseNameRet + '::' + str(i)

            stat_seq = Stat(bname, sname_seq, config, 'normal')
            stat_br = Stat(bname, sname_br, config, 'normal')
            stat_call = Stat(bname, sname_call, config, 'normal')
            stat_ret = Stat(bname, sname_ret, config, 'normal')

            if stat_seq.data() == 1.0:
                self.numSeqFullDom += 1
            elif stat_br.data() == 1.0:
                self.numBrFullDom += 1
            elif stat_call.data() == 1.0:
                self.numCallFullDom += 1
            elif stat_ret.data() == 1.0:
                self.numRetFullDom += 1

            elif stat_seq.data() > 0.0 and stat_br.data() > 0.0 \
                    and stat_call.data() == 0.0 and stat_ret.data() \
                    == 0.0:
                self.numSeqBr += 1

#            elif stat_seq.data() > 0.5 and stat_call.data() == 0.0\
#                    and stat_ret.data() == 0.0:
#                self.numSeqHalfDom += 1
#            elif stat_br.data() > 0.5 and stat_call.data() == 0.0\
#                    and stat_ret.data() == 0.0:
#                self.numBrHalfDom += 1
            else:
                self.numRests += 1

    def data(self):
        return [self.numSeqFullDom, self.numBrFullDom,
                self.numCallFullDom, self.numRetFullDom,
                self.numSeqBr, self.numRests]

def GeometryMean(X):

   return exp(sum([log(x) for x in X]) / len(X))

def ArithmaticMean(X):

    return float(sum([float(x) for x in X]) / float(len(X)))

class DrawingOptions(object):
    def __init__(self, conf, **kwargs):

        if len(conf) < 5 or conf[0] != '!':
            self.valid = False
            return

        self.valid = True

        self.mode = conf[1]
        self.statistics = conf[2].split(',')
        self.benchmarkHint = conf[3]
        self.configurations = conf[4].split(',')
        self.comments = []
        self.graphconf = []
        self.flags = []
        self.legend = []
        self.xticks = []
        self.xsubticks = None
        self.outputName = None
        self.relative = False
        self.mean = True
        self.kiloInsts = False
        self.pdf = False
        self.cdf = False
        self.temp = False
        self.subtract = False
        self.extra = False
        self.ylable = ""
        self.title = ""

        self.drawingDim = 0

        self.benchmarks = []
        if self.benchmarkHint == 'all' :
            self.benchmarks = int_benchmarks + \
                              float_benchmarks + ['Int Mean'] + ['Fp Mean']

        elif self.benchmarkHint == 'int':
            self.benchmarks = int_benchmarks + ['Mean']
        elif self.benchmarkHint == 'fp':
            self.benchmarks = float_benchmarks + ['Mean']

        if len(conf) > 5:
            self.comments = conf[5].split(',')
            # Last element in comments should be the label of y axis
            self.ylabel = unicode(self.comments[-1].replace('_', ' '),
                                  'utf-8')

        if len(conf) > 6:
            self.flags = conf[6].split(',')

        if len(conf) > 7:
            self.graphconf = conf[7].split(',')

        if self.mode == 'SSMB':

            self.drawingDim = 2

            if len(self.statistics) != 1:
                self.valid = False
                print 'In SSMB mode, only one statistics is supported ...'
                return

            comment_len = len(self.comments)
            if comment_len >= len(self.configurations):
                self.legend = self.comments[:len(self.configurations)]
            else:
                self.legend = self.configurations

#            self.outputName = self.flags[-2]
            if comment_len > len(self.configurations):
                self.outputName = self.comments[len(self.configurations)]
            else:
                name = re.sub(':','--',self.statistics[0])
                name = re.sub('\.','-',name)
                self.outputName = name

            if 'relative' in self.flags:
                self.relative = True

            if 'no_mean' in self.flags:
                self.mean = False

            if 'kilo_insts' in self.flags:
                self.kiloInsts = True

        elif self.mode == 'MSMB':

            self.drawingDim = 3
            self.topN = 0

            if len(self.statistics) == 1 and re.match(r'top_\d',\
                    self.statistics[0]):
                self.topN = int(self.statistics[0].split('_')[1])
            elif len(self.statistics) <= 1:
                self.valid = False
                print 'In MSMB mode, you should have more than 1 stat ...'
                return

            if 'extra' in self.flags:
                self.extra = True

            comment_len = len(self.comments)

            if self.topN > 0:
                self.legend = self.comments[:6]
            elif comment_len >= len(self.statistics):
                if self.extra:
                    self.legend = self.comments[:len(self.statistics) - 1]
                else :
                    self.legend = self.comments[:len(self.statistics)]
            else:
                self.legend = self.statistics

#            self.outputName = self.comments[-2]
            if self.topN > 0:
                self.outputName = self.comments[6]
            elif comment_len > len(self.statistics):
                self.outputName = self.comments[len(self.statistics)]
            else:
                name = re.sub(':','--',self.statistics[0])
                name = re.sub('\.','-',name)
                self.outputName = name

            if self.topN > 0:
                self.xsubticks = self.comments[8:comment_len - 1]
            elif comment_len >= len(self.statistics) +\
                              len(self.configurations) + 1:
                self.xsubticks = \
                    self.comments[len(self.statistics) + 1:\
                    comment_len - 1]

            if 'relative' in self.flags:
                self.relative = True

            if 'no_mean' in self.flags:
                self.mean = False

            if 'kilo_insts' in self.flags:
                self.kiloInsts = True

            if 'pdf' in self.flags:
                self.pdf = True

            if 'cdf' in self.flags:
                self.cdf = True

            if 'temp' in self.flags:
                self.temp = True

            if 'subtract' in self.flags:
                self.subtract = True

        elif self.mode == 'SMMB':
            pass

        else:
            print 'Unsupported drawing mode[%s] ...' % self.mode
            self.valid = False

    def isValid(self):
        return self.valid

class Options:pass

if __name__ == '__main__':
    import getpass

    options = Options()
    options.conf= None
   
    opts, args = getopts(sys.argv[1:],'-c:')

    for o,a in opts:
        if o == '-c':
            options.conf= a

    if not options.conf:
        sys.exit('Where is your configuration file?')

    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)

    if not os.path.isdir(result_dir):
        print 'Can not find the directory for stats: %s' % result_dir
        sys.exit(1)

    print 'Read results from %s' % result_dir
    print 'Put figures to %s' % output_dir

    for line in open(options.conf) :

        dp = DrawingOptions(line.split())

        if not dp.isValid():
            continue

        chart = BarChart()

        if dp.drawingDim == 2 and dp.mode == 'SSMB':

            # Add to bar for mean values
            data = np.zeros(len(dp.benchmarks) * (len(dp.configurations)))
            
            data.shape = (len(dp.benchmarks),len(dp.configurations))

            chart.legend = dp.legend
            chart.ylabel = dp.ylabel
            chart.title = dp.title
            chart.xticks = dp.benchmarks

            print 'Drawing %s for %s...' % (dp.statistics[0], \
                    dp.benchmarkHint)

            int_len = len(int_benchmarks)
            fp_len = len(float_benchmarks)

            if dp.benchmarkHint == 'fp':

                for i,bench in enumerate(float_benchmarks):
                    for j,conf in enumerate(dp.configurations):
                        if dp.statistics[0] == 'mpki':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.branchMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_exit':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.exitMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_exit_branch':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.exitAndBranchMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_type_only':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.branchTypeOnlyMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
 
                        elif dp.statistics[0] == 'seq_frac':
                            commit_blocks = Stat(bench,
                                    'system.cpu.commit.commitCommittedInstBlocks', 
                                    conf,
                                    'normal')
                            commit_seqs = Stat(bench,
                                    'system.cpu.commit.commitCommittedSeqInstBlocks',
                                    conf,
                                    'normal')
                            data[i,j] = commit_seqs.data() / commit_blocks.data()
                        elif dp.statistics[0] == 'host_seconds':
                            stat = TempStat(bench, '', conf)
                            data[i,j] = stat.data()
                        else:
                            stat = Stat(bench, dp.statistics[0], conf, 'normal')
                            data[i,j] = stat.data()

            if dp.benchmarkHint == 'all' or dp.benchmarkHint == 'int':

                for i,bench in enumerate(int_benchmarks):
                    for j,conf in enumerate(dp.configurations):
                        if dp.statistics[0] == 'mpki':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.branchMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_exit':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.exitMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_exit_branch':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.exitAndBranchMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_type_only':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.branchTypeOnlyMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
 
                        elif dp.statistics[0] == 'seq_frac':
                            commit_blocks = Stat(bench,
                                    'system.cpu.commit.commitCommittedInstBlocks', 
                                    conf,
                                    'normal')
                            commit_seqs = Stat(bench,
                                    'system.cpu.commit.commitCommittedSeqInstBlocks',
                                    conf,
                                    'normal')
                            data[i,j] = commit_seqs.data() / commit_blocks.data()
                        elif dp.statistics[0] == 'host_seconds':
                            stat = TempStat(bench, '', conf)
                            data[i,j] = stat.data()
                        else:
                            stat = Stat(bench, dp.statistics[0], conf, 'normal')
                            data[i,j] = stat.data()

            if dp.benchmarkHint == 'all':

                for i,bench in enumerate(float_benchmarks):
                    for j,conf in enumerate(dp.configurations):
                        if dp.statistics[0] == 'mpki':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.branchMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i+int_len,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_exit':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.exitMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i+int_len,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_exit_branch':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.exitAndBranchMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i+int_len,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'mpki_type_only':
                            mispredicts = Stat(bench,
                                    'system.cpu.commit.branchTypeOnlyMispredicts', 
                                    conf,
                                    'normal')
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')
                            data[i+int_len,j] = mispredicts.data() /\
                                (commit_insts.data() / 1000.0)
                        elif dp.statistics[0] == 'seq_frac':
                            commit_blocks = Stat(bench,
                                    'system.cpu.commit.commitCommittedInstBlocks', 
                                    conf,
                                    'normal')
                            commit_seqs = Stat(bench,
                                    'system.cpu.commit.commitCommittedSeqInstBlocks',
                                    conf,
                                    'normal')
                            data[i+int_len,j] = commit_seqs.data() / commit_blocks.data()
                        elif dp.statistics[0] == 'host_seconds':
                            stat = TempStat(bench, '', conf)
                        else:
                            stat = Stat(bench, dp.statistics[0], conf, 'normal')
                            data[i+int_len,j] = stat.data()

            if dp.relative:

                if dp.benchmarkHint == 'fp':
                    benches = float_benchmarks
                if dp.benchmarkHint == 'all' or \
                    dp.benchmarkHint == 'int':
                    benches = int_benchmarks
                if dp.benchmarkHint == 'all':
                    benches += float_benchmarks

                for i, bench in enumerate(benches):
                    ref = data[i,0]
                    for j, conf in enumerate(dp.configurations):
                        data[i,j] = data[i,j] / ref

            # Find the arithmatic mean
            if dp.benchmarkHint == 'fp':
                mean_pos = fp_len
                chart.extra_grp = 1

            if dp.benchmarkHint == 'all' or \
               dp.benchmarkHint == 'int':
                mean_pos = int_len
                chart.extra_grp = 1

            if dp.benchmarkHint == 'all':
                mean_pos += fp_len
                chart.extra_grp = 2

            if dp.benchmarkHint == 'fp':

                for j,conf in enumerate(dp.configurations):
                    if dp.mean:
                        data[mean_pos, j] = \
                            ArithmaticMean(data[:fp_len,j])
                    else:
                        data[mean_pos, j] = 0.0


            if dp.benchmarkHint == 'all' or \
               dp.benchmarkHint == 'int':

                for j,conf in enumerate(dp.configurations):
                    if dp.mean:
                        data[mean_pos, j] = \
                            ArithmaticMean(data[:int_len,j])
                    else:
                        data[mean_pos, j] = 0.0

            # Find the arithmatic mean
            if dp.benchmarkHint == 'all':
                for j,conf in enumerate(dp.configurations):
                    if dp.mean:
                        data[int_len+fp_len+1, j] = \
                            ArithmaticMean(data[(int_len):(int_len+fp_len),j])
                    else:
                        data[int_len+fp_len+1, j] = 0.0

	    chart.colormap = 'prism'

        if dp.drawingDim == 3 and dp.mode == 'MSMB':

            # Add to bar for mean values
            if dp.topN > 0:
                data = np.zeros(len(dp.benchmarks) *
                                len(dp.configurations) *
                                6)
            else:
                if dp.extra:
                    data = np.zeros(len(dp.benchmarks) *
                                    len(dp.configurations) *
                                    (len(dp.statistics) - 1))

                    extra = np.zeros(len(dp.benchmarks) *
                                     len(dp.configurations) *
                                     1)
                else :
                    data = np.zeros(len(dp.benchmarks) *
                                    len(dp.configurations) *
                                    len(dp.statistics))
            
            if dp.topN > 0:
                data.shape = (len(dp.benchmarks),
                              len(dp.configurations),
                              6)
            else:
                if dp.extra:
                    data.shape = (len(dp.benchmarks),
                                  len(dp.configurations),
                                  (len(dp.statistics)) - 1)

                    extra.shape = (len(dp.benchmarks),
                                   len(dp.configurations),
                                   1)
                else :
                    data.shape = (len(dp.benchmarks),
                                  len(dp.configurations),
                                  len(dp.statistics))

            chart.legend = dp.legend
            
            stat_base_name = ((dp.statistics[0]).split('::'))[0]

            chart.ylabel = dp.ylabel

            chart.title = dp.title
            chart.xticks = dp.benchmarks

            if dp.xsubticks:
                chart.xsubticks = dp.xsubticks

            print 'Drawing %s for %s...' % (stat_base_name, \
                    dp.benchmarkHint)

            int_len = len(int_benchmarks)
            fp_len = len(float_benchmarks)

            if dp.benchmarkHint == 'fp':

                for i,bench in enumerate(float_benchmarks):
                    for j,conf in enumerate(dp.configurations):

                        if dp.kiloInsts:
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')

                        for k,sname in enumerate(dp.statistics):

                            if dp.pdf:
                                stat = Stat(bench, sname, conf, 'pdf')
                            elif dp.cdf:
                                stat = Stat(bench, sname, conf, 'cdf')
                            elif dp.topN > 0:
                                topN = TopN(bench, conf, dp.topN)
                                stat = [float(x) / \
                                        float(topN.totalNumInstances)
                                        for x in topN.data()]
                            elif dp.temp:
                                stat = TempStat(bench, sname, conf)
                            else:
                                stat = Stat(bench, sname, conf,
                                        'normal')

                            if dp.topN > 0:
                                data[i, j, :] = stat
                            else:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[i,j,0] = stat.data()
                                else :
                                    data[i,j,k] = stat.data()

                            if dp.kiloInsts:
                                data[i,j,k] = data[i,j,k] /\
                                    (commit_insts.data() / 1000.0)

                        if dp.subtract:
                            data[i,j,-1] = \
                                data[i,j,-1] - \
                                sum(data[i,j,x] for x in \
                                        arange(len(data[i,j]) -\
                                            1))
                        if dp.relative:
                            bsum = float(sum(data[i,j]))
                            data[i,j] = data[i,j]/bsum

#                        if conf.split('_')[-2] != 'ei':
#                            data[i,j,1] += data[i,j,0]
#                            data[i,j,0] = 0.0


            if dp.benchmarkHint == 'all' or \
                    dp.benchmarkHint == 'int':

                for i,bench in enumerate(int_benchmarks):
                    for j,conf in enumerate(dp.configurations):

                        if dp.kiloInsts:
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')

                        for k,sname in enumerate(dp.statistics):

                            if dp.pdf:
                                stat = Stat(bench, sname, conf, 'pdf')
                            elif dp.cdf:
                                stat = Stat(bench, sname, conf, 'cdf')
                            elif dp.topN > 0:
                                topN = TopN(bench, conf, dp.topN)
                                stat = [float(x) / \
                                        float(topN.totalNumInstances)
                                        for x in topN.data()]
                            elif dp.temp:
                                stat = TempStat(bench, sname, conf)
                            else:
                                stat = Stat(bench, sname, conf,
                                        'normal')

                            if dp.topN > 0:
                                data[i, j, :] = stat
                            else:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[i,j,0] = stat.data()
                                else :
                                    data[i,j,k] = stat.data()

                            if dp.kiloInsts:
                                data[i,j,k] = data[i,j,k] /\
                                    (commit_insts.data() / 1000.0)

                        if dp.subtract:
                            data[i,j,-1] = \
                                data[i,j,-1] - \
                                sum(data[i,j,x] for x in \
                                        arange(len(data[i,j]) -\
                                            1))
                        if dp.relative:
                            bsum = float(sum(data[i,j]))
                            data[i,j] = data[i,j]/bsum

#                        if conf.split('_')[-2] != 'ei':
#                            data[i,j,1] += data[i,j,0]
#                            data[i,j,0] = 0.0

            if dp.benchmarkHint == 'all':

                for i,bench in enumerate(float_benchmarks):
                    for j,conf in enumerate(dp.configurations):

                        if dp.kiloInsts:
                            commit_insts = Stat(bench,
                                    'system.cpu.committedInsts_total',
                                    conf,
                                    'normal')

                        for k,sname in enumerate(dp.statistics):

                            if dp.pdf:
                                stat = Stat(bench, sname, conf, 'pdf')
                            elif dp.cdf:
                                stat = Stat(bench, sname, conf, 'cdf')
                            elif dp.topN > 0:
                                topN = TopN(bench, conf, dp.topN)
                                stat = [(float(x) / \
                                    float(topN.totalNumInstances))\
                                        for x in topN.data()]
                            else:
                                stat = Stat(bench, sname, conf,
                                        'normal')

                            if dp.topN > 0:
                                data[i+int_len, j, :] = stat
                            else:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[i+int_len,j,0] = stat.data()
                                else :
                                    data[i+int_len,j,k] = stat.data()

                            if dp.kiloInsts:
                                data[i+int_len,j,k] =\
                                    data[i+int_len,j,k] /\
                                    (commit_insts.data() / 1000.0)

                        if dp.subtract:
                            data[i+int_len,j,-1] = \
                                data[i+int_len,j,-1] - \
                                sum(data[i+int_len,j,x] for x in \
                                        arange(len(data[i+int_len,j]) -\
                                            1))
            # Find the arithmatic mean
            if dp.benchmarkHint == 'fp':
                mean_pos = fp_len
                chart.extra_grp = 1

            if dp.benchmarkHint == 'all' or \
               dp.benchmarkHint == 'int':
                mean_pos = int_len
                chart.extra_grp = 1

            if dp.benchmarkHint == 'all':
                mean_pos += fp_len
                chart.extra_grp = 2

            if dp.benchmarkHint == 'fp':
                for j,conf in enumerate(dp.configurations):
                    if dp.topN > 0:
                        for k in range(6):
                            data[mean_pos, j, k] = \
                                    ArithmaticMean(data[:fp_len, j, k])
                    else:
                        for k,sname in enumerate(dp.statistics):
                            if dp.mean:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[mean_pos, j, 0] = \
                                        GeometryMean(extra[:fp_len, j, 0])
                                else :
                                    data[mean_pos, j, k] = \
                                        ArithmaticMean(data[:fp_len, j, k])

                            else:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[mean_pos, j, 0] = 0.0
                                else :
                                    data[mean_pos, j, k] = 0.0

            if dp.benchmarkHint == 'all' or \
               dp.benchmarkHint == 'int':
                for j,conf in enumerate(dp.configurations):
                    if dp.topN > 0:
                        for k in range(6):
                            data[mean_pos, j, k] = \
                                    ArithmaticMean(data[:int_len, j, k])
                    else:
                        for k,sname in enumerate(dp.statistics):
                            if dp.mean:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[mean_pos, j, 0] = \
                                        GeometryMean(extra[:int_len, j, 0])
                                else :
                                    data[mean_pos, j, k] = \
                                        ArithmaticMean(data[:int_len, j, k])

                            else:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[mean_pos, j, 0] = 0.0
                                else :
                                    data[mean_pos, j, k] = 0.0

            # Find arithmatic mean
            if dp.benchmarkHint == 'all':
                for j,conf in enumerate(dp.configurations):
                    if dp.topN > 0:
                        for k in range(6):
                            data[int_len+fp_len+1, j, k] = \
                                    ArithmaticMean(data[int_len:int_len+fp_len,\
                                        j, k])
                    else:
                        for k,sname in enumerate(dp.statistics):
                            if dp.mean:

                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[int_len+fp_len+1, j, 0] = \
                                        GeometryMean(extra[(int_len):(int_len+fp_len),\
                                            j, 0])
                                else :
                                    data[int_len+fp_len+1, j, k] = \
                                        ArithmaticMean(data[(int_len):(int_len+fp_len),\
                                            j, k])

                            else:
                                if dp.extra and k == len(dp.statistics) - 1 :
                                    extra[int_len+fp_len+1, 0] = 0.0
                                else :
                                    data[int_len+fp_len+1, j] = 0.0

            chart.colormap = 'prism'

        chart.data = data
        if dp.extra:
            chart.extra = extra
        else :
            chart.extra = None

#        chart.xlabel = 'Benchmarks'
#        chart.ylim = (0.0,1.0)
#        chart.legend_size = 10.5
        chart.legend_size = 8
#        chart.ytick_log = True
#        chart.ylim = True
#        chart.yticks = ['0%', '20%', '40%', '60%', '80%', '100%']
#        chart.legend_loc = 'upper center'
#        chart.fig_legend = None
#        chart.figure_size = [0.08,0.26,0.9,0.54]
#        chart.figure_size = [0.1,0.22,0.86,0.48]
#        chart.figure_size = [0.1,0.24,0.76,0.54]
        if len(dp.graphconf) >= 8: 
            chart.figure_size = [float(dp.graphconf[0]),\
                                 float(dp.graphconf[1]),\
                                 float(dp.graphconf[2]),\
                                 float(dp.graphconf[3])]
            chart.xlabel_rotation = float(dp.graphconf[4])
            chart.legend_col = int(dp.graphconf[5])
            chart.colormap = dp.graphconf[6]
            if dp.graphconf[7] == 'hatch' :
                chart.hatch_enable = True
            else :
                chart.hatch_enable = False
#        chart.figure_size = [0.1,0.26,0.86,0.51]
#        chart.chart_size = [7,2.625]
        chart.chart_size = [5.5,2.2625]
        chart.ygrid = True
	chart.graph()

        fname = dp.outputName
#        chart.savefig(joinpath(output_dir, 'png', fname + '.png'))
        chart.savefig(joinpath(output_dir, 'pdf', fname + '.pdf'))
#        chart.savefig(joinpath(output_dir, 'eps', fname + '.eps'))
#        chart.savefig(joinpath(output_dir, 'ps', fname + '.ps'))
	chart.savecsv(joinpath(output_dir, 'csv', fname + '.csv'))

